#pragma once

#include <iostream>
#include <memory>
#include <functional>
#include <sys/wait.h>
#include "Socket.hpp"

namespace TcpServerModule
{
    using namespace SocketModule;
    using tcphandler_t = std::function<bool(SockPtr, InetAddr)>;
    // TcpServer只负责进行IO,不对协议做任何的处理
    class TcpServer
    {
    public:
        TcpServer(int port)
            : _listensockfd(std::make_unique<TcpSocket>()),
              _isrunning(false), _port(port)
        {
        }
        void InitTcpServer(tcphandler_t handler)
        {
            _handler = handler;
            _listensockfd->BuildTcpSocketMethod(_port);
        }
        void Loop() //循环
        {
            _isrunning=true;
            while(_isrunning)
            {
                //1.accept
                InetAddr client;  //保存客户端信息
                auto sockfd=_listensockfd->Accepter(&client); 
                if(sockfd==nullptr)
                {
                    continue;
                }
                //2.IO通信
                //孙子进程
                int id=fork();
                if(id==0)  //子进程
                {
                    _listensockfd->Close();
                    if(fork())  //子进程直接退出,孙子进程执行任务
                    {
                        exit(0);
                    }
                    //孙子进程
                    _handler(sockfd,client); //执行回调方法
                    exit(0);
                }
                //父进程
                sockfd->Close();
                waitpid(id,nullptr,0);
            }
            _isrunning=false;
        }
        ~TcpServer()
        {
            _listensockfd->Close();
        }
    private:
        std::unique_ptr<Socket> _listensockfd; // 一定要有一个监听的
        bool _isrunning;
        int _port;
        tcphandler_t _handler;
    };
}